#include "data.h"
#include <stdlib.h>
#include <time.h>

int data_src[4][4];
int blank = 14;

void data_init(void)
{
    int i,j;
    for (i = 0;i < 4;i++)
        for (j = 0;j < 4;j++)
            data_src[i][j] = 0;
    srand(time(NULL));

    create_new_data();
    create_new_data();
}
int log2N(int num)
{
    int i = 0;
    while ((num = num >> 1) != 0)
        i++;
    return i;
}
int create_new_data(void)
{
    int new_value = (((rand() % 5) < 1) ? 4 : 2);
    int blank_num = 0;
    int i,j;
    for (i = 0;i < 4;i++)
    {
        for (j = 0;j < 4;j++)
        {
            if (data_src[i][j] == 0)
                blank_num++;
        }
    }
    blank = blank_num;
    if (blank_num == 0)        
        return 0;
    int pos = rand() % blank_num;
    for (i = 0;i < 4;i++)
    {
        for (j = 0;j < 4;j++)
        {
            if (data_src[i][j] == 0)
                pos--;
            else continue;
            if (pos == -1)
            {
                data_src[i][j] = new_value;
                goto update_value;
            }
        }
    }
    update_value:return new_value;
}
void up()
{
    int i,j,k;
    int *blank_pos = NULL;
    for (j = 0;j < 4;j++)
    {
        for (i = 0;i < 3;i++)
        {
            if (data_src[i][j] == 0)
                continue;
            for (k = 1;k < 4 - i;k++)
            {

                if (data_src[i + k][j] != data_src[i][j] && data_src[i + k][j] != 0)
                    break;
                if (data_src[i + k][j] == data_src[i][j])
                {
                    data_src[i][j] <<= 1;
                    data_src[i + k][j] = 0;
                    break;
                }
            }
        }
        blank_pos = NULL;
        for (i = 0;i < 4;i++)
        {
            if ((blank_pos == NULL) && (data_src[i][j] == 0))
            {
                blank_pos = &(data_src[i][j]);
            }
           else if ((blank_pos != NULL) && (data_src[i][j] != 0))
            {
                *blank_pos = data_src[i][j];
                data_src[i][j] = 0;
                blank_pos += 4;
            }
        }
    }
}
void down()
{
    int i,j,k;
    int *blank_pos = NULL;
    for (j = 0;j < 4;j++)
    {
        for (i = 3;i > 0;i--)
        {
            if (data_src[i][j] == 0)
                continue;
            for (k = 1;k <= i;k++)
            {

                if (data_src[i - k][j] != 0 && data_src[i - k][j] != data_src[i][j])
                    break;
                if (data_src[i - k][j] == data_src[i][j])
                {
                    data_src[i][j] <<= 1;
                    data_src[i - k][j] = 0;
                    break;
                }
            }
         }
        blank_pos = NULL;
        for (i = 3;i >= 0;i--)
        {
            if ((blank_pos == NULL) && (data_src[i][j] == 0))
                blank_pos = &(data_src[i][j]);
            else if ((blank_pos != NULL) && (data_src[i][j] != 0))
            {
                *blank_pos = data_src[i][j];
                data_src[i][j] = 0;
                blank_pos -= 4;
            }
        }
    }
}
void left()
{
    int i,j,k;
    int *blank_pos = NULL;
    for (i = 0;i < 4;i++)
    {
        for (j = 0;j < 3;j++)
        {
            if (data_src[i][j] == 0)
                continue;
            for (k = 1;k < 4 - j;k++)
            {

                if (data_src[i][j + k] != 0 && data_src[i][j + k] != data_src[i][j])
                    break;
                if (data_src[i][j + k] == data_src[i][j])
                {
                    data_src[i][j] <<= 1;
                    data_src[i][j + k] = 0;
                    break;
                }
            }
        }
        blank_pos = NULL;
        for (j = 0;j < 4;j++)
        {
            if ((blank_pos == NULL) && (data_src[i][j] == 0))
            {
                blank_pos = &(data_src[i][j]);
            }
            else if ((blank_pos != NULL) && (data_src[i][j] != 0))
            {
                *blank_pos = data_src[i][j];
                data_src[i][j] = 0;
                blank_pos += 1;
            }
        }
    }
}
void right()
{
    int i,j,k;
    int *blank_pos = NULL;
    for (i = 0;i < 4;i ++)
    {
        for (j = 3;j > 0;j--)
        {
            if (data_src[i][j] == 0)
                continue;
            for (k = 1;k <= j;k++)
            {

                if (data_src[i][j - k] != 0 && data_src[i][j - k] != data_src[i][j])
                    break;
                if (data_src[i][j - k] == data_src[i][j])
                {
                    data_src[i][j] <<= 1;
                    data_src[i][j - k] = 0;
                    break;
                }
            }
        }
        blank_pos = NULL;
        for (j = 3;j >= 0;j--)
        {
            if ((blank_pos == NULL) && (data_src[i][j] == 0))
            {
                blank_pos = &(data_src[i][j]);
            }
            else if ((blank_pos != NULL) && (data_src[i][j] != 0))
            {
                *blank_pos = data_src[i][j];
                data_src[i][j] = 0;
                blank_pos -= 1;
            }
        }
    }
}
int game_is_over()
{
    int i,j;
    if (blank != 0)
        return 0;
    for (i = 0;i < 4;i++)
    {
        for (j = 0;j < 3;j++)
            if (data_src[i][j] == data_src[i][j + 1])
                return 0;
    }
    for (j = 0;j < 4;j++)
    {
        for (i = 0;i < 3;i++)
            if (data_src[i][j] == data_src[i + 1][j])
                return 0;
    }
    return 1;
}
